import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px


# 读取奖牌数据
def read_medals():
    filepath = "../file/Medals.xlsx"
    df = pd.read_excel(filepath)
    # print(df.head(10))
    # print(df.shape)
    # print(df.info())
    return df


# 读取 运动员数据
def read_athlete():
    filepath = "../file/Athletes.xlsx"
    df = pd.read_excel(filepath)
    return df

# 读取 男女运动员数据
def read_athlete_sex():
    filepath = "../file/EntriesGender.xlsx"
    gender = pd.read_excel(filepath)
    return gender

# 奖牌 前30 的数据统计
def top_30_medal():
    df = read_medals()
    # 数据  类型转换
    df['Team/NOC'] = df['Team/NOC'].astype(str)
    # print(df.info())
    # 奖牌数据分析 与 可视化
    #  数据 降序
    # Q1:   统计 奖牌 排名 前30的
    top_30 = df.sort_values(by='Total', ascending=False)[:30]
    # figure.figsize
    #  设置大小
    plt.rcParams['figure.figsize'] = (25, 7)
    # 画柱状图 x 轴  y 轴
    ax = sns.barplot(x=top_30['Team/NOC'], y=top_30['Total'], palette='tab20c')
    ax.bar_label(ax.containers[0])
    # 设置 X轴
    ax.set_xlabel(xlabel='Countries', fontsize=10)
    # 设置Y轴
    ax.set_ylabel(ylabel='Total Medal Count', fontsize=10)
    # 设置  标题
    ax.set_title(label='Top 30 winners', fontsize=20)

    plt.xticks(rotation=90)
    plt.show()


# 前 10 名国家在奖牌总数中的总份额。
def top_10_share():
    df = read_medals()
    plt.style.use("seaborn-talk")
    # 获取 奖牌  总数量
    series_df = df.groupby('Team/NOC')['Total'].sum().sort_values(ascending=False)

    labels = []
    values = []
    others_count = 0;
    count = 0
    # print(series_df.head(10))
    for country in series_df.index:
        if count < 10:
            labels.append(country)
            values.append(series_df[country])
        else:
            others_count += series_df[country]
        count += 1
    labels.append('others')
    values.append(others_count)

    explode = (0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
    plt.title(f"Total Share of in total medals from top 10 countries ")
    print(len(labels))
    wedge_dict = {
        'edgecolor': 'black',
        'linewidth': 2
    }
    plt.pie(values, labels=labels, explode=explode, autopct='%1.1f%%', wedgeprops=wedge_dict, shadow=True,
            startangle=90)
    # plt.pie(values, labels=labels,  autopct='%1.1f%%', wedgeprops=wedge_dict,
    #         shadow=True, startangle=90)
    plt.show()


# 银牌份额的饼图表示
def silver_medal_top10():
    df = read_medals()
    silver_df = df.groupby('Team/NOC')['Silver'].sum().sort_values(ascending=False)

    count = 0
    labels = []
    values = []
    others_count = 0
    for c in silver_df.index:
        if count < 10:
            labels.append(c)
            values.append(silver_df[c])
        else:
            others_count += silver_df[c]
        count += 1
    labels.append("others")
    values.append(others_count)

    explode = (0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
    plt.title(f"Total Share in Silver medals of various countries ")
    wedge_dict = {
        'edgecolor': 'black',
        'linewidth': 2
    }
    plt.pie(values, labels=labels, explode=explode, autopct="%1.0f%%", wedgeprops={'edgecolor': 'black', 'linewidth': 1}
            , shadow=True, startangle=50)

    plt.show()


# Question 3: 前20个 国家 金牌数量
def top_20_medals():
    df = read_medals()
    top_20_country = df.sort_values(by=["Gold"], ascending=False)[:20]
    # 设置 大小
    fig, axes = plt.subplots(1, 1, figsize=(25, 9))
    # 设置 x y palette(调色板)数据
    ax = sns.barplot(x=top_20_country['Team/NOC'], y=top_20_country['Gold'], palette="tab20c")
    # print(ax.containers[0])
    ax.bar_label(ax.containers[0])
    plt.xticks(rotation=45)
    plt.title('Top 20 countries to win most Gold medals.')
    plt.show()


# 金牌数低于8的国家会在其他国家显示  饼图
def less8_medals():
    df = read_medals()
    df_new = df.groupby('Team/NOC')['Gold'].sum().sort_values(ascending=False)
    count = 0
    other_total = 0
    labels = []
    values = []
    for c in df_new.index:
        if df_new[c] >= 8:
            labels.append(c)
            values.append(df_new[c])
        # 低于 8 的数量
        else:
            other_total += df_new[c]
    labels.append("others")
    values.append(other_total)
    explode = (0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
    # 饼图数据显示
    plt.title("Total Share in Gold medals of various countries")
    # 渲染数据
    plt.pie(values, labels=labels, explode=explode, autopct="%1.01f%%",
            wedgeprops={'edgecolor': 'black', 'linewidth': 1}, shadow=True, startangle=90)
    plt.show()


# 获得最多银牌的前 20 个国家。
def silver_top_20():
    df = read_medals()
    # print(df.head())
    # df_new = df.groupby("Team/NOC")['Silver'].sum().sort_values(ascending=False)[:20]
    df_new = df.sort_values(by=['Silver'], ascending=False)[:20]
    # print(df_new.head(21))
    # 设置 柱状图 大小
    fig, axes = plt.subplots(1, 1, figsize=(30, 12))
    ax = sns.barplot(x=df_new['Team/NOC'], y=df_new['Silver'], palette="tab20c")
    ax.bar_label(ax.containers[0])
    plt.xticks(rotation=90)
    plt.title('Top 20 countries to win most Silver medals.')
    plt.show()


# 银牌数少于 8 的国家将显示在其他国家  饼图
def silver_less_8_medals():
    df = read_medals()
    # print(df.head())
    df_new = df.groupby('Team/NOC')['Silver'].sum().sort_values(ascending=False)
    # print(df_new.head())
    labels = []
    values = []
    others_total = 0
    for c in df_new.index:
        if df_new[c] < 8:
            others_total += df_new[c]
        else:
            labels.append(c)
            values.append(df_new[c])
    labels.append("others")
    values.append(others_total)
    explode = (0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
    # 设置 饼图 大小
    plt.title("Total Share in Silver medals of various countries")
    plt.pie(values, labels=labels, explode=explode, autopct="%1.01f%%",
            wedgeprops={'edgecolor': 'black', 'linewidth': 1}, shadow=True, startangle=90)
    plt.show()


# 铜牌 前20名 排行榜
def bronze_top_20():
    df = read_medals()
    df_new = df.sort_values(by=['Bronze'], ascending=False)[:20]
    # print(df_new.head())
    fig, axes = plt.subplots(1, 1, figsize=(25, 12))
    ax = sns.barplot(x=df_new['Team/NOC'], y=df_new['Bronze'], palette="tab20c")
    ax.bar_label(ax.containers[0])
    plt.xticks(rotation=90)
    plt.title("Top 20 countries to win most Bronze medals.")
    plt.show()


# 铜牌数少于10的国家将显示在其他国家
def bronze_less_10_medals():
    df = read_medals()
    # print(df.head(10))
    df_new = df.groupby("Team/NOC")['Bronze'].sum().sort_values(ascending=False)
    # print(df_new.head(10))
    labels = []
    values = []
    others_total = 0

    for c in df_new.index:
        if df_new[c] < 10:
            others_total += df_new[c]
        else:
            labels.append(c)
            values.append(df_new[c])
    labels.append(c)
    values.append(others_total)

    explode = (0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
    # 饼图 绘制
    plt.title("Total Share in Bronze medals of various countries")
    plt.pie(values, labels=labels, explode=explode, autopct="%1.01f%%",
            wedgeprops={"edgecolor": "black", "linewidth": 2}, shadow=True, startangle=90)
    plt.show()


# 每个国家 奖牌 分布
def each_country_medals():
    data = read_medals()
    # fig = px.choropleth(data,locations="Team/NOC",locationmode="country names",color="Team/NOC",hover_name="Total",
    #               range_color=[1,100],color_continuous_scale="blues",title="Density of Countries in 2020")
    fig = px.choropleth(data, locations="Team/NOC",
                        locationmode='country names', color="Team/NOC",
                        hover_name="Total", range_color=[1, 100],
                        color_continuous_scale="blues",
                        title='Density of Countries in 2020')
    fig.update(layout_coloraxis_showscale=True)
    fig.show()


# 代表运动员最多的前 20 个国家
def top_20_athlete():
    athlete = read_athlete()
    pivot_tab = pd.pivot_table(athlete,index=['NOC'],values=['Name'],aggfunc={'Name':'count'})
    res = pivot_tab.sort_values(by=['Name'],ascending=False)
    # print(res)
    # 设置大小
    plt.figure(figsize=(25,9))
    splt = sns.barplot(x=res.head(20).index,y='Name',data=res[:20])
    splt = sns.barplot(x=res.head(20).index,y=res['Name'][:20])
    # X 轴 回转
    plt.xticks(rotation="vertical")
    plt.bar_label(splt.containers[0])
    plt.title("Top 20 Countries with the most respresenting athletes",fontweight="bold",fontsize=20)
    plt.show()

#   代表运动员人数最少的国家。
def people_less():
    athlete = read_athlete()
    pivot_tab = pd.pivot_table(athlete,index=['NOC'],values=['Name'],aggfunc={"Name":'count'})
    res = pivot_tab.sort_values(by=['Name'],ascending=True)
    # 设置大小
    plt.figure(figsize=(25,9))
    splot = sns.barplot(x=res.head(20).index,y='Name',data=res.head(20))
    # 设置 x轴  回转
    plt.xticks(rotation=90)
    plt.bar_label(splot.containers[0])
    plt.title("Countries with the least number of respresenting athletes",fontweight="bold",fontsize=20)
    plt.show()

# 列出最具代表性的运动员的前 30 个学科
def athlete_top_30():
    athlete = read_athlete()
    # print(athlete.head())
    pivot_tab = pd.pivot_table(athlete,index=['Discipline'],values=['Name'],aggfunc={"Name":"count"})
    res = pivot_tab.sort_values(by=["Name"],ascending=False)

    # 设置 柱状图 大小
    plt.figure(figsize=(25,9))

    # 渲染数据
    splot = sns.barplot(x=res.head(30).index,y='Name',data=res.head(30))
    # 设置 X轴 回转
    plt.xticks(rotation=90)
    # 设置标题
    plt.title("Top 30 Disciplines with the most respresenting Athletes",fontweight="bold",fontsize=20)
    plt.show()

# 各个国家/地区的运动员数量
def each_country_athlete():
    athlete = read_athlete()
    # df_new = data.groupby('NOC')['Name'].count().sort_values(ascending=False)
    count = athlete.groupby(by=['NOC','Discipline']).count()
    # print(count.head())
    grouped = athlete[:30].groupby(by = ['NOC','Discipline']).count()
    grouped.plot.barh()
    plt.show()

    # 世界地图显示了各自学科的国家
    c=[]
    d=[]
    for i in range(len(count.index)):
        c.append(count.index[i][0])
    for i in range(len(count.index)):
        d.append(count.index[i][1])
    # 2020年国家密度
    fig = px.choropleth([count,athlete], locations=c,
                        locationmode='country names', color=c,
                        hover_name=c,hover_data=[count.Name,d], range_color=[1,100],
                        color_continuous_scale="blues",
                        title='Density of Countries in 2020')
    fig.update(layout_coloraxis_showscale=True)
    fig.show()

# 各项比赛  运动员 男女性别比
def athlete_sex():
    gender = read_athlete_sex()
    gender=gender.sort_values(by='Total',ascending=False)[:15]
    A = gender.plot(kind="bar",x = 'Discipline',y =['Female','Male'],figsize=(18,8)).legend(loc='upper center',ncol=3);
    plt.title("Genders",size=20,weight='bold')
    plt.show()

if __name__ == '__main__':
    # 奖牌 数据 分布情况
    # top_30_medal()
    # top_10_share()
    # silver_medal_top10()
    # top_20_medals()
    # less8_medals()
    # silver_top_20()
    # silver_less_8_medals()
    # bronze_top_20()
    # bronze_less_10_medals()
    # each_country_medals()

    # 运动员 数据 分布情况
    # top_20_athlete()
    # people_less()
    # athlete_top_30()
    # each_country_athlete()
    athlete_sex()